/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.ui.widgets;

import info.xmlprint.font.FontInfo;
import info.xmlprint.font.FontManager;
import info.xmlprint.run.Configuration;
import info.xmlprint.ui.message.GuiMessages;
import info.xmlprint.util.FileUtil;

import java.io.File;
import java.util.ArrayList;

import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;

public class SetupComposite {
	private Composite pageComp;
	private StackLayout stackLayout = new StackLayout();
	private Composite generalComp, otherComp;
	private FontComposite fontComposite;
	private Button pathButton;

	private Combo engineCombo;

	private Text enginePath;

	private String[] listItemNames = new String[] {
			GuiMessages.General_Gui_General, GuiMessages.General_Gui_Fonts,
			GuiMessages.General_Gui_Extended };

	private String[] satzEngineItemNames = new String[] { "XML-Print" };

	public SetupComposite(Composite parent) {
		initGui(parent);
	}

	private void initGui(Composite parent) {
		pageComp = new Composite(parent, SWT.NONE);
		pageComp.setLayout(new GridLayout());

		SashForm sashForm = new SashForm(pageComp, SWT.BORDER);
		sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));

		{
			List list = new List(sashForm, SWT.BORDER);
			list.setItems(listItemNames);
			list.addListener(SWT.Selection, new Listener() {
				public void handleEvent(Event e) {
					List list = (List) e.widget;
					int selectIndex = list.getSelectionIndex();
					if (selectIndex == 0) {
						stackLayout.topControl = generalComp;
					} else if (selectIndex == 1) {
						stackLayout.topControl = fontComposite.getComposite();
					} else if (selectIndex == 2) {
						stackLayout.topControl = otherComp;
					}

					otherComp.getParent().layout();
				}
			});

			list.select(0);

		}

		{
			Composite comp = new Composite(sashForm, SWT.BORDER);
			comp.setLayout(stackLayout);
			generalComp = getGeneralComp(comp);
			fontComposite = new FontComposite(comp);
			otherComp = getOtherComp(comp);

			stackLayout.topControl = generalComp;
			sashForm.setWeights(new int[] { 1, 4 });
		}

		addFootComp(pageComp);

	}

	private void addFootComp(Composite parent) {
		Composite buttonComp = new Composite(parent, SWT.NONE);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = GridData.END;
		buttonComp.setLayoutData(gridData);

		RowLayout rowLayout = new RowLayout();
		rowLayout.pack = false;
		rowLayout.spacing = 15;
		buttonComp.setLayout(rowLayout);

		// save
		Button okButton = new Button(buttonComp, SWT.NONE);
		okButton.setText(GuiMessages.General_Gui_Okay);
		okButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				writeConfigFile();
				pageComp.getShell().dispose();
			}
		});

		Button cancelButton = new Button(buttonComp, SWT.NONE);
		cancelButton.setText(GuiMessages.General_Gui_Cancel);
		cancelButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				pageComp.getShell().dispose();
			}
		});

		// apply
		final Button applyButton = new Button(buttonComp, SWT.NONE);
		applyButton.setText(GuiMessages.General_Gui_Apply);
		applyButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				writeConfigFile();
				applyButton.setEnabled(false);
			}
		});
	}

	private void writeConfigFile() {
		Configuration config = Configuration.getInstance();
		config.setValue("engineName", getEngineComboSelect());
		config.setValue("enginePath", enginePath.getText());
	}

	private String getEngineComboSelect() {
		return engineCombo.getItem(engineCombo.getSelectionIndex());
	}

	private void setEngineText() {
		enginePath.setEnabled(true);
		pathButton.setEnabled(true);
	}

	// Allgemein Composite
	private Composite getGeneralComp(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		comp.setLayout(new GridLayout());
		Group group = new Group(comp, SWT.TOP);
		group.setText(GuiMessages.General_Engine);
		{
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			group.setLayoutData(gd);
		}
		group.setLayout(new GridLayout());
		engineCombo = new Combo(group, SWT.NONE);
		{
			GridData gd = new GridData();
			engineCombo.setLayoutData(gd);
		}
		engineCombo.setItems(satzEngineItemNames);
		String engineName = Configuration.getInstance()
				.getValueOf("engineName");
		if (engineName != null && !engineName.equals("")) {
			int index = 0;
			for (String s : engineCombo.getItems()) {
				if (s.equals(engineName)) {
					engineCombo.select(index);
					break;
				}
				index++;
			}
		}
		engineCombo.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event arg0) {
				setEngineText();
			}

		});
		enginePath = new Text(group, SWT.BORDER | SWT.MULTI | SWT.WRAP);
		{
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.heightHint = 50;
			enginePath.setLayoutData(gd);
		}

		enginePath.setText(Configuration.getInstance().getEnginePath());
		pathButton = new Button(group, SWT.NONE);
		pathButton.setText(" Change ");

		pathButton.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				FileDialog dialog = new FileDialog(pathButton.getShell(),
						SWT.OPEN);
				dialog.setFilterNames(new String[] { ".exe" });
				dialog.setFilterExtensions(new String[] { "*.exe", "*.*" });

				String dir = enginePath.getText();
				if (!dir.equals("")) {
					File file = new File(dir);
					if (file != null) {
						String parent = file.getParent();
						if (new File(parent).isDirectory()) {
							dialog.setFilterPath(parent);
						}
					}
				}

				String filePath = dialog.open();

				if (filePath != null) {
					enginePath.setText(filePath);
				}
			}
		});

		setEngineText();
		return comp;
	}

	// Erweitere
	private Composite getOtherComp(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		comp.setLayout(new GridLayout());
		new Label(comp, SWT.NONE).setText(" ... ");

		return comp;
	}

	// Gui testen
	public static void main(String args[]) {
		Display display = Display.getDefault();
		Shell shell = new Shell(display, SWT.RESIZE | SWT.APPLICATION_MODAL);
		shell.setSize(660, 450);
		shell.setText(GuiMessages.General_Menu_Settings);
		shell.setLayout(new FillLayout());

		new SetupComposite(shell);

		shell.layout();
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();

		}
		shell.dispose();
	}

}

class FontComposite {
	private TreeViewer tv;
	// private Button ttfButton, otfButton, pfbButton;

	String fontSelect;

	private java.util.List<FontInfo> fontInfoList = new ArrayList<FontInfo>();

	private Composite mainComp;

	public FontComposite(Composite parent) {
		initGui(parent);
	}

	private void initGui(Composite parent) {
		mainComp = new Composite(parent, SWT.NONE);
		mainComp.setLayout(new GridLayout());
		new Label(mainComp, SWT.NONE)
				.setText(GuiMessages.General_Gui_Systemfonts + ":");

		addTreeViewer(mainComp);
		refresh();

		new Label(mainComp, SWT.NONE);

		Button button = new Button(mainComp, SWT.NONE);
		button.setText(" " + GuiMessages.General_Gui_Add + " ");
		button.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				FileDialog fileDialog = new FileDialog(mainComp.getShell(),
						SWT.OPEN | SWT.MULTI);
				fileDialog.setFilterNames(new String[] { "*.ttf" });
				fileDialog
						.setFilterExtensions(new String[] { "*.ttf", "*.otf" });

				fileDialog.open();
				String fileNames[] = fileDialog.getFileNames();

				if (fileNames.length > 0) {
					FontManager fontManager = FontManager.getInstance();
					for (String s : fileNames) {
						File f1 = new File(fileDialog.getFilterPath() + "/" + s);
						File f2 = new File(Configuration.getInstance()
								.getXmlprintFontsDir() + s);
						FileUtil.copyFile(f1, f2);
						fontManager.registerFile(f2.getAbsolutePath());
					}
					refresh();
					// tv.refresh();
				}

			}
		});
	}

	/*
	 * Font Dateien wieder in allen verzeichnis neu suchen
	 */
	public void refresh() {
		new Thread() {
			public void run() {
				fontInfoList = FontManager.getInstance().getFontInfoList();
				Display.getDefault().syncExec(new Runnable() {
					public void run() {
						if (!tv.getTree().isDisposed())
							tv.setInput(fontInfoList);
					}
				});
			}
		}.start();
	}

	public Composite getComposite() {
		return mainComp;
	}

	private void addTreeViewer(Composite parent) {
		tv = new TreeViewer(parent, SWT.FULL_SELECTION | SWT.MULTI);

		final Tree tree = tv.getTree();
		tree.setLayoutData(new GridData(GridData.FILL_BOTH));
		tree.setHeaderVisible(true);
		tree.setLinesVisible(true);
		TableLayout tableLayout = new TableLayout();
		tree.setLayout(tableLayout);

		tv.setContentProvider(new ITreeContentProvider() {
			public void dispose() {
			}

			public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
			}

			public Object[] getChildren(Object arg0) {
				return null;
			}

			public Object[] getElements(Object arg0) {
				if (arg0 instanceof ArrayList) {
					@SuppressWarnings("unchecked")
					ArrayList<FontInfo> list = (ArrayList<FontInfo>) arg0;
					ArrayList<FontInfo> out = new ArrayList<FontInfo>();

					for (FontInfo fm : list) {
						if (fm.getSelected().equals("true")) {
							out.add(fm);
						}
					}
					return (FontInfo[]) out.toArray(new FontInfo[out.size()]);
				}
				return null;
			}

			public Object getParent(Object arg0) {
				return null;
			}

			public boolean hasChildren(Object arg0) {
				return false;
			}
		});

		tv.setLabelProvider(new ITableLabelProvider() {

			public void addListener(ILabelProviderListener arg0) {
			}

			public void dispose() {
			}

			public boolean isLabelProperty(Object arg0, String arg1) {
				return false;
			}

			public void removeListener(ILabelProviderListener arg0) {
			}

			public Image getColumnImage(Object arg0, int arg1) {
				return null;
			}

			public String getColumnText(Object arg0, int arg1) {

				if (!(arg0 instanceof FontInfo))
					return null;

				FontInfo f = (FontInfo) arg0;

				if (arg1 == 0) {
					return f.getFontName();
				} else if (arg1 == 1) {
					return f.getFontType();
				} else if (arg1 == 2) {
					return f.getFontVariable();
				} else
					return f.getFontPath();
			}

		});

		{
			// TODO
			{
				TreeColumn tc = new TreeColumn(tree, SWT.LEFT_TO_RIGHT);
				tc.setText("Name");
				tc.setWidth(120);
			}
			{
				TreeColumn tc = new TreeColumn(tree, SWT.LEFT_TO_RIGHT);
				tc.setText("Type");
				tc.setWidth(50);
			}
			{
				TreeColumn tc = new TreeColumn(tree, SWT.LEFT_TO_RIGHT);
				tc.setText("Variant");
				tc.setWidth(80);
			}
			{
				TreeColumn tc = new TreeColumn(tree, SWT.LEFT_TO_RIGHT);
				tc.setText("Path");
				tc.setWidth(200);
			}
		}

	}
}
